<?php
/*
 * (C) Copyright 2013 Torsten Gorath (http://www.blauesdach.de/).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Contributors:
 *     Torsten Gorath
 */
require_once $basedir . '/conf/config.php';
class Database {

    private $conn = null;
    static private $inst = null;

    static public function getDefault() {
        if (null === self::$inst) {
            self::$inst = new Database();
        }
        return self::$inst;
    }

    /**
     * @param $tablename Dieses ist der Tabellenname, welcher auch als Objektname
     *                   verwendet wird.
     * @param id die id aus der Datenbank
     * @param {String} [$classname] if tablename and classname the same set to
     *                              null
     */
    public function openId($tablename, $id, $classname=null) {
        global $VEREIN;
        if($classname == null) {
            $classname = $tablename;
        }
        $query = "SELECT * FROM " . $VEREIN['prefix'] . $tablename . " WHERE id='" . $id . "';";
        $result = $this->query($query);
        $object = $result->fetch_object($classname);//mysql_fetch_object($result, $classname);
        return $object;
    }
    
    public function deleteId($classname, $id) {
        global $VEREIN;
        $query = "DELETE FROM " . $VEREIN['prefix'] . $classname." WHERE id='".$id."';";
        $result = $this->query($query);
        return TRUE;
    }

    /**
     * Used to insert Data.
     * 
     * @param $table database tablename
     * @param $insertes assoc array with data to insert
     * @return new ID
     */
    public function insert($table, $inserts) {
        global $VEREIN;
        $values = array_map(array($this->conn, 'escape_string'), array_values($inserts));
        $keys = array_keys($inserts);
        $query = 'INSERT INTO `' . $VEREIN['prefix'] . $table . '` (`'.implode('`,`', $keys).'`) VALUES (\''.implode('\',\'', $values).'\')';
        $result = $this->query($query);
        if(!$result) {
        	echo mysql_error();
            throw new Exception("Can't insert object into database", 1);
        }
        if($result->insert_id == 0) {
            return true;
        }
        return $result->insert_id;
    }
    
    public function update($table, $data, $id) {
        global $VEREIN;
        $query = "UPDATE " . $VEREIN['prefix'] . $table . " SET ";
        $i = 0;
        foreach($data as $key => $value) {
        	$i++;
            if(is_bool($value)) {
                $query .= $key."='".($value?1:0)."'";
            } else {
                $query .= $key."='".$value."'";
            }
			if($i<count($data)) {
				$query .= ", ";
			}
        }
        $query .= " WHERE id='".$id."'";
        $result = $this->query($query);
        if(!$result) {
            throw new Exception("Can't update object in database", 1);
            return false;
        }
        return true;
    }
    public function executePrepare($query, $assoc=null, $classname="") {
        $array = array();
        $stmt = $this->conn->prepare($query);
        if(!$stmt) {
            throw new Exception("Prepare failed: (".$this->conn->errno.") ".$this->conn->error);
        }
        if($assoc != null) {
            foreach($assoc as $value=>$type) {
                $stmt_r = null;
                if(!$stmt->bind_param($type, $value)) {
                    throw new Exception("Binding failed: (".$this->conn->errno.") ".$this->conn->error);
                }
            }
        }
        $execute = $stmt->execute();
        if(!$stmt->execute()) {
            throw new Exception("Execute failed: (".$this->conn->errno.") ".$this->conn->error);
        }
        if(!(stripos($query, "delete") === false) 
            || !(stripos($query, "update") === false)
            || !(stripos($query, "truncate") === false)
            || !(stripos($query, "create") === false)
            || !(stripos($query, "alter") === false)) {
            return $execute;
        }
        $result = $stmt->get_result();
        if(!(stripos($query, "insert") === false)) {
            return $result->insert_id;
        }
        
        if(!$result) {
            die($this->conn->error . "<br />" . $query);
        }
        if($classname=="") {
            while($row = $result->fetch_assoc()) {
                array_push($array, $row);
            }
        } else {
            while($row = $result->fetch_object($classname)) {
                array_push($array, $row);
            }
        }
        $result->free();
        return $array;
    }
    
    public function execute($query,$classname="") {
        $array = array();
        $result = $this -> query($query);
        if(!$result) {
            die($this->conn->error . "<br />" . $query);
        }
		if($classname=="") {
		    while($row = $result->fetch_assoc()) {
		        array_push($array, $row);
		    }
		} else {
		    while($row = $result->fetch_object($classname)) {
		        array_push($array, $row);
		    }
		}
        $result->free();
        return $array;
    }
    
    public function getConnection() {
        return $this->conn;
    }

    private function query($query) {
        $result = $this->conn->query($query);
        if(!$result) {
            throw new Exception("Can't execute " . $query . ". Message: " . $this->conn->error);
        }
/*        $result = mysql_query($query, $this->conn);
        if (!$result) {
            throw new Exception("Can't execute ".$query.". Message: ".mysql_error($this->conn));
        }*/
        return $result;
    }

    private function __construct() {
        global $VEREIN;
        $this->conn = new mysqli($VEREIN["server"], $VEREIN["user"], $VEREIN["password"], $VEREIN["datenbank"]);
        if($this->conn->connect_errno) {
            throw new Exception("Could not open database connection");
        }
/*        $this->conn = mysql_connect($VEREIN["server"], $VEREIN["user"], $VEREIN["password"]);
        if (!$this->conn) {
            throw new Exception("Could not open database connection");
        }
        if (!mysql_select_db($VEREIN["datenbank"], $this->conn)) {
            throw new Exception("Database does not exist");
        };*/
    }

    private function __clone() {
    }

}
?>